/*
    封装请求工具--utils--request.js
    1 初始化 axios 实例
    2 请求拦截器 头部 带上 token
    3 响应拦截器 拿出响应数据 拦截失效 token
    4 导出 axios 实例--函数形式--返回 Promise
*/
import axios from 'axios'
import store from '@/store'
import router from '@/router'
/**
 *  axios 重试 --axios-retry
 *
 * 1. 安装axios-retry
 * npm install axios-retry
 * 2. 引入模块
 * import axiosRetry from 'axios-retry'
 * 3. 配置axios-retry
 // 传入axios实例
axiosRetry(instance, {
	retries: 2, // 设置自动发送请求次数
	retryDelay: () => 0.5 * 1000, // 重复请求延迟（毫秒）
	shouldResetTimeout: true, //  重置超时时间
	// return true为打开自动发送请求，false为关闭自动发送请求
	retryCondition: error =>
		error.message.includes('timeout') || error.message.includes('404'),
})
 */

// 导出 URL  其他不是通过axios 请求的地址 使用这个
export const baseURL = 'https:apipc-xiaotuxian-front.itheima.net/'

// 1 创建 axios实例
const instance = axios.create({
	baseURL,
	timeout: 5000,
})
// 2 axios   拦截器
// 请求 成功  失败   发请求之前拦截
// use 里面两个   回调函数 config为回调函数参数   成功与失败对应执行
// 拦截后一定要返回出去  config 不然下以后的axios就无法获取config
instance.interceptors.request.use(
	config => {
		// 拦截后做什么  也可create时处理
		// 1 config.headers config.url 等处理config
		// 2 弹框等 延时组件  完事后 响应拦截去掉
		// 3 登录等 要携带信息token  没有可以跳转对应界面

		// 如果本地存在token  就携带token  vuex
		// 1获取用户信息 对象
		const { profile } = store.state.user
		// 2判断是否有token
		if (profile && profile.token) {
			// 3携带token
			config.headers.Authorization = `Bearer ${profile.token}`
		} else {
			// 4没有token 跳转登录
			// router.push('/login')
		}
		// 最后返回出去 处理后的config
		return config
	},
	err => Promise.reject(err)
)
// 3 响应 成功  失败   回调函数  数据返回之前拦截
instance.interceptors.response.use(
	//  最后返回出去 处理后的v  后台数据
	v => v.data,
	e => {
		/*
		    401 进入该函数
         1 清空无效用户信息
         2 跳转到登录页面
         3 跳转到登录页面 应携带当前路由地址 以便跳回  取 route.query.redirect
				 组件中‘/user?a=10&b=1’ $route.path === /user   携带数据丢失
				                   $route.fullPath === /user?a=10
				 router.currentRoute 是 ref响应式 数据  .value
				 ? & 等特殊字符要转码 encodeURIComponent  防止解析地址错误
      */
		if (e.response && e.response.status === 401) {
			store.commit('user/setUser', {})
			const fullPath = encodeURIComponent(router.currentRoute.value.fullPath)
			router.push(`/login?redirect=${fullPath}`)
		}
		return Promise.reject(e)
	}
)
/*
   4 返回 promise
   请求地址 请求方式 请求数据
   1 get params 来提交 submitData
   2 post data 提交 submitData
   { [ 可写 表达式 ] : value} 动态 key
    get Get  GET   统一转为小写 toLowerCase()
*/
export default (method, url, submitData) =>
	// 3 发送网络请求   返回一个 fulfill 状态的axios
	// 即promise  v.data  为服务器返回数据 v包含6个
	instance({
		method,
		url,
		[method.toLowerCase() === 'get' ? 'params' : 'data']: submitData,
	})

/*
	   跨域  同源策略
		 1 vue.config.js  配置
		 target  替换  之前的 baseURL
		 2 baseURL  改为
		 const baseURL = '/api'

  const { defineConfig } = require('@vue/cli-service')
  module.exports = defineConfig({
	transpileDependencies: true,
	devServer: {
		proxy: {
			'/api': {
				target: 'http://park.puyizu.com/', //这里填入你要请求的接口的前缀
				ws: true, //代理webSocked
				changeOrigin: true, //虚拟的站点需要更管origin
				secure: true, //是否https接口
				pathRewrite: {
					'^/api': '', //重写路径
				},
			},
		},
	},
})

// 1 默认  的格式请求体中的数据会以json字符串的形式发送到后端
  'Content-Type: application/json '
// 2 请求体中的数据会以普通表单形式（键值对）发送到后端
  'Content-Type: application/x-www-form-urlencoded'
// 3 它会将请求体的数据处理为一条消息，以标签为单元，用分隔符分开。既可以上传键值对，也可以上传文件
  'Content-Type: multipart/form-data'

	// 1 创建 axios实例
const instance = axios.create({
	baseURL,
	timeout: 5000,
	headers: {
		'Content-Type': 'application/json',
	},
})

  Promise

	async
	try 中
	默认 最后一行 为 返回值
	没写--return undefined      .then(resolve=>undefined)
	return 'aa'                .then(resolve=>aa)    ======
	return Promise.resolve(v)  .then(resolve=>v)

	catch 中
	return ‘aa’                .then(resolve=>aa)  解决了
	return Promise.reject(error)    catch 到        =======

	export const useQQLoginSavePush = async apiFn => {
	try {
		const { result } = await apiFn()
		return 'success'
	} catch (error) {
		return Promise.reject(error)
	}
}

	*/
